const Base_Response = require('../../ws_frame/client/class/Base_Response.js');

class Response extends Base_Response{
    static MODE = {
        DEFAULT: "DEFAULT",
        EVENT_PlayerMessage: "EVENT_PlayerMessage",
        CMD_RESPONSE: "CMD_RESPONSE",
    };
    static MESSAGE_TEMPLATES = {
        [Response.MODE.DEFAULT]: {
            "header": {
                "messagePurpose": CONSTANTS.MESSAGE_PURPOSE.BDS_REQUEST,
                "version": 17039360,
                "requestId": "no requestId",

                "url": undefined,
                "source_bds_uuid": undefined,       // 源BDSuuid, 涉及到客户端间通信时主动设置
                "source_bds_serverName": undefined, // 源BDSName, 涉及到客户端间通信时主动设置
                "request_bds_uuid": undefined,
                "request_bds_serverName": undefined,
            },
            "body": {
                "data": {},
                "statusCode": 0,
                "statusMessage": ""
            }
        },
        [Response.MODE.EVENT_PlayerMessage]:{ 
            "header": {
                "messagePurpose": CONSTANTS.MESSAGE_PURPOSE.EVENT,
                "version": 17039360,
                "requestId": "no requestId",
                "eventName": 'PlayerMessage',
                "request_bds_uuid": undefined,
                "request_bds_serverName": undefined,
            },
            "body": { 
                "message": '', 
                "receiver": '', 
                "sender": '', 
                "type": 'chat' 
            },
        },
        [Response.MODE.CMD_RESPONSE]:{
            "header": {
                "messagePurpose": CONSTANTS.MESSAGE_PURPOSE.CMD_RESPONSE,
                "version": 17039360,
                "requestId": "no requestId",
            },
            "body": {
                "data": {},
                "statusCode": 0,
                "statusMessage": ""
            }
        }
    };

    /**
     * 回复请求
     * @param {Request} req - 请求对象
     * @returns {Response} 响应对象
     */
    static replyTo(req, mode = Response.MODE.DEFAULT) {
        const response = new Response(mode);
        req?.header?.requestId && response.setRequestId(req.header.requestId);
        return Response._copyContext(req, response);
    }

    /**
     * 从请求对象创建响应对象
     * @param {Request} req - 请求对象
     * @returns {Response} 响应对象
     */
    static fromRequest(req, mode = Response.MODE.DEFAULT) {
        const response = new Response(mode);
        return Response._copyContext(req, response);
    }

    /**
     * 复制请求上下文到响应对象
     * @param {Request} req - 请求对象
     * @param {Response} response - 响应对象
     * @returns {Response} 响应对象
     */
    static _copyContext(req, response) {
        if (req && req.header) {
            response.header.source_bds_uuid = req.header.source_bds_uuid;
            response.header.source_bds_serverName = req.header.source_bds_serverName;
        }
        return response;
    }

    constructor(mode = Response.MODE.DEFAULT){
        super();
        this.mode = mode;
        this.json = JSON.parse(JSON.stringify(Response.MESSAGE_TEMPLATES[mode] || Response.MESSAGE_TEMPLATES[Response.MODE.DEFAULT]));
        this.header = this.json.header;
        this.body = this.json.body;
        this.data = this.json.body.data;

        // 统一设置共同请求头
        this.header.requestId = utils.uuidv4();
        this.header.version = 17039360;
        this.header.request_bds_uuid = CONF.CONFIG.get('Websocket')['BDSUuid'];
        this.header.request_bds_serverName = CONF.CONFIG.get('Websocket')['ServerName'];
    }

    /**
     * 支持链式调用
     * @param {Function} modifier - 修改json的回调函数
     * @returns {Response} Response实例
     */
    tap(modifier) {
        if (typeof modifier === 'function') {
            modifier(this);
            return this;
        }else{
            throw new Error('modifier must be a function');
        }
    }

    /**
     * 设置URL
     * @param {string} url - URL
     * @returns {Response} Response实例
     */
    setUrl(url){
        this.header.url = url;
        return this;
    }

    /**
     * 设置请求ID
     * @param {string} requestId - 请求ID
     * @returns {Response} Response实例
     */
    setRequestId(requestId){
        this.header.requestId = requestId;
        return this;
    }

    /**
     * 设置消息目的
     * @param {string} messagePurpose - 消息目的
     * @returns {Response} Response实例
     */
    setMessagePurpose(messagePurpose){
        this.header.messagePurpose = messagePurpose;
        return this;
    }

    /**
     * 设置响应事件名称
     * @param {string} eventName - 事件名称
     * @returns {Response} Response实例
     */
    setEventName(eventName){
        this.body.eventName = eventName;
        return this;
    }

    /**
     * 设置状态码
     * @param {number} statusCode - 状态码
     * @returns {Response} Response实例
     */
    setStatusCode(statusCode){
        this.body.statusCode = statusCode;
        return this;
    }

    /**
     * 设置状态消息
     * @param {string} statusMessage - 状态消息
     * @returns {Response} Response实例
     */
    setStatusMessage(statusMessage){
        this.body.statusMessage = statusMessage;
        return this;
    }

    /**
     * 设置sourceId
     * @param {string} sourceId - WS连接ID
     * @returns {Response} Response实例
     */
    setSourceId(sourceId){
        this.header.sourceId = sourceId;
        return this;
    }

    /**
     * 设置source_bds_uuid
     * @param {string} source_bds_uuid - BDS UUID
     * @returns {Response} Response实例
     */
    setSourceBdsUuid(source_bds_uuid){
        this.header.source_bds_uuid = source_bds_uuid;
        return this;
    }

    /**
     * 设置source_bds_serverName
     * @param {string} source_bds_serverName - BDS 服务器名称
     * @returns {Response} Response实例
     */
    setSourceBdsServerName(source_bds_serverName){
        this.header.source_bds_serverName = source_bds_serverName;
        return this;
    }
    
    /**
     * 设置数据
     * @param {object} data - 数据
     * @returns {Response} Response实例
     */
    setData(data){
        this.body.data = data;
        return this;
    }

    /**
     * 设置元数据
     * @param {object} metaData - 元数据
     * @returns {Response} Response实例
     */
    setMetaData(metaData){
        this.body.metaData = metaData;
        return this;
    }
}

module.exports = Response;